/* 
 * File:   Module.h
 * Author: Piotrek
 *
 * Created on 24 kwiecień 2010, 22:16
 */

#ifndef _MODULE_H
#define	_MODULE_H

#include "Triangle.h"
#include <vector>
#include "stdafx.h"
#include <ctype.h>

extern float I[4][4];
/**
 * @brief Moduł robota
 * 
 * Największy element robota stanowiący bryłę sztywną, bez elementów ruchomych.
 * @n see @ref matrix-transformations\n
 */
class Module {
public:

    /// kat obrotu wzgledem poprzedniego modulu
    float R;
    /// os obrotu wzgledem poprzedniego modulu
    char axis;
    float X;    ///<przesuniecie w kierunku X wzgledem poprzedniego modulu
    float Y;    ///<przesuniecie w kierunku Y wzgledem poprzedniego modulu
    float Z;    ///<przesuniecie w kierunku Z wzgledem poprzedniego modulu
    /// macierz transformacji
    float T[4][4];
    /// trojkaty tworzece modul
    std::vector< Triangle > triangles;

	unsigned int vertexCount;
	unsigned int faceCount;   

	float * vertices;
	float * vertices0;

	float * normals;
	float * normals0;

	int * indices;

    /**
     * Glowny konstruktor dla oniekty typu Module.     
     *  @param filepath - sciezka do pliku STL
     *  @param x0,y0,z0 - wspolrzedne modulu WZGLEDEM MODULU POPRZEDNIEGO
     *  @param axis - znak char [x|y|z] odpowiadajacy glownej osi obrotu
     */
    Module(char * filepath, float x0, float y0, float z0, char axis);

    /**
     * Konstruktor przyjmujace pozostale parametry zerowe.
     *  @param filepath - sciezka do pliku STL
     */
    Module(char* filepath);


    /**
     * @brief
     * Dodanie trojkatow do istniejacego modulu bezposrednio z pliku
     *
     * Mozliwe jest natychmiastowa translacja wszystkich trojkatow o zadany wektor.
     * Natomiast niemozliwa jest rotacja.
     *
     * @param filepath - sciezka do pliku
     * @param tx,ty,tz - wspolrzedne do translacji trojkatow o wektor
     */
    int addTriangles(char * filepath, float tx, float ty, float tz);

    /**
     * @brief
     * Przepisanie trojkatow z modułu module do modułu wywołującego funkcje.
     *
     * @param module - wskaznik do modulu z trojkatami do przepisania
     */
    void addTriangles(Module * module);

    /**
     * @brief Odczyt trojkatow z pliku STL ASCII
     * 
     * Trojkaty zostana dopisane do modulu, ktory wywowal funkcje.
     * @n Mozliwa jest translacja trojkatow o dany wektor od razu przy wczytywaniu.
     * 
     * @param filepath sciezka do pliku
     * @param tx,ty,tz wspolczynniki translacji trojkatow
     */
    int readTrianglesFromStl(char * filepath, float tx, float ty, float tz);

	int readArraysFromPly(char * filepath);

    /// rysowanie modulu w srodowisku OpenGL
    void drawModule();
    
    /**
     * Przesuniecie modulu o dany wektor.
     * Zamiast tej funkcji lepiej uzywac transform()
     */
    void translate(float x, float y, float z);


    /**
     * @brief
     * Uniwersalna funkcja dokonujaca transformarcji (translacja + rotacja) modulu.
     *
     * Transformacja dokonywana jest na zasadzie skladania obrotow. Podstawy teoretyczne: http://www.robotyka.com/teoria.php/teoria.43.
     * Nowe polozenie jest wyliczane na podstawie wzoru:
     * @n [x,y,z]' = [Tprev]*[T]*[x0,y0,z0]', gdzie Tprev,T-macierze, x,y,z - wspolrzedne
     *
     * Funkcja jest zoptymalizowana do wykonywania rotacji tylko wzgledem jednej osi jednoczenie.
     *
     * @param X, Y, Z   wspolrzedne translacji
     * @param axis  oś rotacji, znak char [x|y|z] lub wartosc 0
     * @param R     kąt rotacji, w stopniach
     * @param Tprev   macierz transformacji poprzedniego modulu lub macierz jednostkowa I
     * @param whichTriangles   0 -aktualizacja trojkatow zerowych, !0 aktualizacja trojkotow rzeczywistych zobacz @ref Triangle
     */
    void transform(float X, float Y, float Z, float axis, float R, float Tprev[4][4], int whichTriangles);

    /**
     * Transformacja na podstawie macierzy transformacji T wzgledem poprzedniego modulu.
     * @n Za parametry X,Y,Z,axis,R - brane sa odpowiadajace im parametry modulu.
     * @n forceUpdate = 0
     * @param Tprev macierz transformacji poprzedniego modulu
     */
    void transform(float Tprev[4][4]);

};

#endif	/* _MODULE_H */

